package main

import "flag"

import (
	"github.com/coreos/capnslog"
	"os"
	"os/signal"
	"proxy/api"
	"proxy/backend"
	"proxy/meta"
	"proxy/recorder"
	"sync"
	"time"
	mylog "proxy/log"
//	"fmt"
)

var optApiAddr string
var optBackendAddr string
var optJobDir string
var optLogLevel string
var optMaxRtc int
var optLogDir string

func main() {

	parseOptions()

	repoLogger := capnslog.MustRepoLogger("proxy")
	if logLevel, err := repoLogger.ParseLogLevelConfig(optLogLevel); err != nil {
		log.Errorf("could not parse log level: %s", err)
		return
	} else {
		repoLogger.SetLogLevel(logLevel)
	}

	state := &ProxyState{
		api:      api.NewServer(optApiAddr),
		backend:  backend.NewServer(optBackendAddr),
		meta:     meta.NewDatabase(),
		recorder: recorder.NewManager(optJobDir),
	}

	state.api.SetEventHandler(NewApiHandler(state))
	state.backend.SetEventHandler(NewBackendHandler(state))
	state.meta.SetEventHandler(&metaHandler{state})
	var wg sync.WaitGroup

	wg.Add(1)
	go func() {
		state.api.Run()
		wg.Done()
	}()

	wg.Add(1)
	go func() {
		state.backend.Run()
		wg.Done()
	}()

	wg.Add(1)
	go func() {
		state.meta.Run()
		wg.Done()
	}()

	wg.Add(1)
	go func() {
		state.recorder.Run()
		wg.Done()
	}()

	go state.handleSignal()

	wg.Wait()
}

func parseOptions() {
	flag.StringVar(&optApiAddr, "api", ":2018", "api listen address, default to ':2018'")
	flag.StringVar(&optBackendAddr, "backend", ":2019", "backend listen addr, default to ':2019'")
	flag.StringVar(&optJobDir, "job-dir", "/tmp/recorder/jobs", "where to create job file, default to '/tmp/recorder/jobs'")
	flag.StringVar(&optLogLevel, "log-level", "*=INFO", "log level, e.g. -log-level=main=INFO,*=ERROR")
	flag.IntVar(&optMaxRtc, "max-rtc", 100, "max rtc per backend, defaulted to 100")
	flag.StringVar(&optLogDir, "log-dir", "log", "log dir, defaulted to log")

	flag.Parse()
	tNow := time.Now()
	timeNow := tNow.Format("2006-01-02 15:04:05")
	mylog.Init(optLogDir, "proxy"+timeNow[0:10])
	
	log.Infof("optApiAddr='%s'", optApiAddr)
	log.Infof("optBackendAddr='%s'", optBackendAddr)
	log.Infof("optJobDir='%s'", optJobDir)
	log.Infof("optLogLevel='%s'", optLogLevel)
	log.Infof("optMaxRtc=%d", optMaxRtc)
	log.Infof("optLogDir='%s'", optLogDir)
	
}

type ProxyState struct {
	meta     *meta.Database
	api      *api.Server
	backend  *backend.Server
	recorder *recorder.Manager
}

func (p *ProxyState) handleSignal() {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	select {
	case s, ok := <-c:
		if !ok {
			return
		}
		log.Warningf("received signal '%v', exiting", s)
		p.api.Close()
		p.backend.Close()
		p.meta.Close()
		p.recorder.Close()
	}
}
